package com.qf.contract.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.qf.common.base.exception.BaseException;
import com.qf.common.base.exception.ServiceException;
import com.qf.common.base.result.ResultCode;
import com.qf.contract.entity.*;
import com.qf.contract.mapper.FContractDetailsMapper;
import com.qf.contract.mapper.FContractMapper;
import com.qf.contract.mapper.FContractRecycleBinMapper;
import com.qf.contract.mapper.FSigningUnitMapper;
import com.qf.contract.qo.FContractDetailsQo;
import com.qf.contract.qo.FContractQo;
import com.qf.contract.qo.SigningUnitQo;
import com.qf.contract.service.ContractService;
import com.qf.contract.utils.IdGeneratorSnowflake;
import com.qf.contract.vo.ContractRecordQueryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 合同登记
 */
@Service
public class ContractServiceImpl implements ContractService {
    @Resource
    private FContractMapper fContractMapper;
    @Resource
    private FContractDetailsMapper fContractDetailsMapper;
    @Resource
    private FSigningUnitMapper fSigningUnitMapper;
    @Resource
    private FContractRecycleBinMapper fContractRecycleBinMapper;
    private int num = 0;
    //引入雪花算法类

    /**
     * 增加合同分支
     *
     * @return
     */
    @Override
    public IPage<ContractRecordQueryVo> contractRecordQuery(int current, int size) {
        IPage<ContractRecordQueryVo> page;
        try {
            MPJLambdaWrapper<FContract> wrapper = new MPJLambdaWrapper<FContract>()
                    .selectAll(FContract.class)//查询user表全部字段
                    .selectAll(FContractDetails.class)
                    .selectAll(FTypeOfContract.class)
                    .selectAll(FSigningUnit.class)

                    .leftJoin(FContractDetails.class, FContractDetails::getContractId, FContract::getContractDetails)
                    .leftJoin(FTypeOfContract.class, FTypeOfContract::getContractId, FContract::getTypeOfContract)
                    .leftJoin(FSigningUnit.class, FSigningUnit::getUnitId, FContract::getSigningUnit);
//        List<ContractRecordQueryOV> List = fContractMapper.selectJoinList(ContractRecordQueryOV.class, wrapper);
            //TODO 分页连表查询
            page = fContractMapper.selectJoinPage(new Page<>(current, size), ContractRecordQueryVo.class, wrapper);
        } catch (Exception e) {
            throw new ServiceException(ResultCode.SYS_ERROR);
        }
        return page;
    }

    /**
     * 增加合同分支
     *
     * @return
     */
    @Override
    public int addfContractDetails(FContractDetailsQo fContractDetailsQo) {
        num = 0;
        try {
            FContractDetails fContractDetails = new FContractDetails();
            BeanUtils.copyProperties(fContractDetailsQo, fContractDetails);
            num = num + fContractDetailsMapper.insert(fContractDetails);
            if (num != 1) {
                throw new RuntimeException();
            }
        } catch (Exception e) {
            throw new ServiceException(ResultCode.SYS_ERROR);
        }
        return num;
    }

    /**
     * 增加合同分支
     *
     * @param fContractQo
     * @return
     */
    @Override
    public int addfContract(FContractQo fContractQo) {
        num = 0;
        try {
            //给合同编号赋值
            //生成项目编号
            fContractQo.setContractNumber(IdGeneratorSnowflake.getSonwFlakeId().toString());
            //创建po对象
            FContract fContract = new FContract();
            //对po对象进行赋值
            BeanUtils.copyProperties(fContractQo, fContract);
            System.out.println(fContract);
            //插入增加语句
            num = num + fContractMapper.insert(fContract);
            if (num != 1) {
                throw new RuntimeException();
            }
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new ServiceException(ResultCode.SYS_ERROR);
        }
        return num;
    }

    /**
     * 增加合同plus
     *
     * @param fContractQo
     * @param signingUnitQo
     * @param fContractDetailsQo
     * @return
     */
    @Override
    public int addfContractPlus(FContractQo fContractQo, SigningUnitQo signingUnitQo, FContractDetailsQo fContractDetailsQo) {
        num = 0;
        try {
            //给合同编号赋值
            //生成项目编号
            fContractQo.setContractNumber(IdGeneratorSnowflake.getSonwFlakeId().toString());
            //创建po对象
            FContract fContract = new FContract();
            FContractDetails fContractDetails = new FContractDetails();
            FSigningUnit fSigningUnit = new FSigningUnit();

            //对po对象进行赋值
            BeanUtils.copyProperties(fContractQo, fContract);
            BeanUtils.copyProperties(fContractDetailsQo, fContractDetails);
            BeanUtils.copyProperties(signingUnitQo, fSigningUnit);

            /**
             * 对数据进行赋值
             */
            num = num + fSigningUnitMapper.insert(fSigningUnit);
            num = num + fContractDetailsMapper.insert(fContractDetails);
            num = num + fContractMapper.insert(fContract);
            if (num < 3) {
                throw new RuntimeException();
            }

//            addfContractDetails(fContractDetailsQo);
//            addsigningUnit(signingUnitQo);
//            addfContract(fContractQo);

        } catch (RuntimeException e) {
            throw new BaseException(ResultCode.INSERT_ERROR);
        } catch (Exception e) {
            throw new ServiceException(ResultCode.SYS_ERROR);
        }
        return num;
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Transactional
    @Override
    public int delContract(List ids, int operatorId) {
        try {
            for (Object id : ids) {
                FContractRecycleBin fContractRecycleBin = new FContractRecycleBin();
                fContractRecycleBin.setOperatorId(operatorId);
                fContractRecycleBin.setRecoveredId((Integer) id);
                fContractRecycleBinMapper.insert(fContractRecycleBin);
            }

            return fContractMapper.deleteBatchIds(ids);
        } catch (Exception e) {
            throw new ServiceException(ResultCode.SYS_ERROR);
        }
    }

    /**
     * 数据恢复
     *
     * @param fContractRecycleBin
     * @return
     */
    @Override
    @Transactional
    public int deleted_Recovery(FContractRecycleBin fContractRecycleBin) {
        /**
         * 查出所有的这个用户的回收站
         */
        try {
            List<FContractRecycleBin> fContractRecycleBinsList = fContractRecycleBinMapper.selectList(
                    new QueryWrapper<FContractRecycleBin>().eq("operator_id", fContractRecycleBin.getOperatorId()));
            /**
             * 遍历读出每一条记录
             */
            for (FContractRecycleBin recycleBin : fContractRecycleBinsList) {
                /**
                 * 将这个用户的合同注键赋值给持久化层
                 */
                FContract fContract = new FContract();
                fContract.setContractId(recycleBin.getRecoveredId());
                fContract.setContractStatus(0);
                fContractMapper.dataRecovery(fContract);
                /**
                 * 同时将这个回收站的这一条记录逻辑删除
                 */
                return fContractRecycleBinMapper.deleteById(recycleBin.getRecycleBinId());
            }
        } catch (Exception e) {
            throw new ServiceException(ResultCode.SYS_ERROR);
        }
        return 0;
        //数据恢复
    }

    /**
     * 添加合同详细
     *
     * @param signingUnitQo
     * @return
     */

    @Override
    public int addsigningUnit(SigningUnitQo signingUnitQo) {
        num = 0;
        try {
            FSigningUnit fSigningUnit = new FSigningUnit();
            BeanUtils.copyProperties(signingUnitQo, fSigningUnit);
            num = num + fSigningUnitMapper.insert(fSigningUnit);
            if (num != 1) {
                throw new RuntimeException();
            }
        } catch (Exception e) {
            throw new ServiceException(ResultCode.SYS_ERROR);
        }
        return num;
    }
}
